using System;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace AreaBuilder.Forms {
    public partial class frmResets : Form {
        private readonly AreaHolder ah;
        private int inArray = -1;

        public frmResets() {
            InitializeComponent();
        }

        public frmResets(AreaHolder ah, int value) {
            InitializeComponent();

            this.ah = ah;
            inArray = value;
        }

        private void frmResets_Load(object sender, EventArgs e) {
            if (inArray >= 0) {
                inArray--;
                var r = (Reset) ah.area.Resets[inArray];

                if (r.Type.Equals("M")) {
                    cmbType.SelectedIndex = 0;

                    selectVNum(cmbVNum, r.VNum);
                    selectVNum(cmbLocation, Int32.Parse(r.VNumWear));

                    txtLimit.Text = r.Limit.ToString();
                    txtLimit2.Text = r.ExtraParam;
                } else if (r.Type.Equals("O")) {
                    cmbType.SelectedIndex = 1;

                    selectVNum(cmbVNum, r.VNum);
                    selectVNum(cmbLocation, Int32.Parse(r.VNumWear));

                    txtLimit.Text = r.Limit.ToString();
                } else if (r.Type.Equals("P")) {
                    cmbType.SelectedIndex = 2;

                    selectVNum(cmbVNum, r.VNum);
                    selectVNum(cmbLocation, Int32.Parse(r.VNumWear));

                    txtLimit.Text = r.Limit.ToString();
                    txtLimit2.Text = r.ExtraParam;
                } else if (r.Type.Equals("G")) {
                    cmbType.SelectedIndex = 3;

                    selectVNum(cmbVNum, r.VNum);
                    try {
                        selectVNum(cmbLocation, Int32.Parse(r.VNumWear));
                    } catch (Exception) {
                        selectVNum(cmbLocation, -1);
                    }

                    txtLimit.Text = r.Limit.ToString();
                } else if (r.Type.Equals("E")) {
                    cmbType.SelectedIndex = 4;

                    selectVNum(cmbVNum, r.VNum);
                    selectVNum(cmbLocation, Int32.Parse(r.VNumWear));

                    txtLimit.Text = r.Limit.ToString();
                } else if (r.Type.Equals("D")) {
                    cmbType.SelectedIndex = 5;

                    selectVNum(cmbVNum, r.VNum);
                    selectVNum(cmbExits, r.Limit);
                    selectVNum(cmbLocation, Int32.Parse(r.VNumWear));
                } else if (r.Type.Equals("R")) {
                    cmbType.SelectedIndex = 6;

                    selectVNum(cmbVNum, r.VNum);
                    selectVNum(cmbExits, r.Limit);
                }
            } else
                cmbType.SelectedIndex = 0;
        }

        private void cmbType_SelectedIndexChanged(object sender, EventArgs e) {
            cmbVNum.Items.Clear();
            cmbLocation.Items.Clear();

            #region CMBTYPE

            if (cmbType.SelectedIndex == 0) {
                // M
                fillComboboxMobs(cmbVNum);
                fillComboboxRooms(cmbLocation);

                lblVNum.Enabled = true;
                lblLimit.Enabled = true;
                lblLocationVNum.Enabled = true;
                lblLimit2.Enabled = true;
                cmbVNum.Enabled = true;
                txtLimit.Visible = true;
                cmbExits.Visible = false;
                txtLimit.Enabled = true;
                cmbLocation.Enabled = true;
                txtLimit2.Enabled = true;


                lblVNum.Text = "Mobile VNum:";
                lblLimit.Text = "Area Limit:";
                lblLocationVNum.Text = "Room VNum:";
                lblLimit2.Text = "Room Limit:";
            } else if (cmbType.SelectedIndex == 1) {
                // O
                fillComboboxItems(cmbVNum);
                fillComboboxRooms(cmbLocation);

                lblVNum.Enabled = true;
                lblLimit.Enabled = true;
                lblLocationVNum.Enabled = true;
                lblLimit2.Enabled = false;
                cmbVNum.Enabled = true;
                txtLimit.Visible = true;
                cmbExits.Visible = false;
                txtLimit.Enabled = true;
                cmbLocation.Enabled = true;
                txtLimit2.Enabled = false;

                lblVNum.Text = "Object VNum:";
                lblLimit.Text = "Global Limit:";
                lblLocationVNum.Text = "Room VNum:";
            } else if (cmbType.SelectedIndex == 2) {
                // P
                fillComboboxItems(cmbVNum);
                fillComboboxItemsContainer(cmbLocation);

                lblVNum.Enabled = true;
                lblLimit.Enabled = true;
                lblLocationVNum.Enabled = true;
                lblLimit2.Enabled = true;
                cmbVNum.Enabled = true;
                txtLimit.Visible = true;
                cmbExits.Visible = false;
                txtLimit.Enabled = true;
                cmbLocation.Enabled = true;
                txtLimit2.Enabled = true;

                lblVNum.Text = "Object VNum:";
                lblLimit.Text = "Global Limit:";
                lblLocationVNum.Text = "Container VNum:";
                lblLimit2.Text = "Copies:";
            } else if (cmbType.SelectedIndex == 3) {
                // G
                fillComboboxItems(cmbVNum);
                fillComboboxWears(cmbLocation);

                lblVNum.Enabled = true;
                lblLimit.Enabled = true;
                lblLocationVNum.Enabled = true;
                lblLimit2.Enabled = false;
                cmbVNum.Enabled = true;
                txtLimit.Visible = true;
                cmbExits.Visible = false;
                txtLimit.Enabled = true;
                cmbLocation.Enabled = true;
                txtLimit2.Enabled = false;

                lblVNum.Text = "Object VNum:";
                lblLimit.Text = "Global Limit:";
                lblLocationVNum.Text = "Wear Location:";
            } else if (cmbType.SelectedIndex == 4) {
                // E
                fillComboboxItems(cmbVNum);
                fillComboboxWears(cmbLocation);

                lblVNum.Enabled = true;
                lblLimit.Enabled = true;
                lblLocationVNum.Enabled = true;
                lblLimit2.Enabled = false;
                cmbVNum.Enabled = true;
                txtLimit.Visible = true;
                cmbExits.Visible = false;
                txtLimit.Enabled = true;
                cmbLocation.Enabled = true;
                txtLimit2.Enabled = false;

                lblVNum.Text = "Object VNum:";
                lblLimit.Text = "Global Limit:";
                lblLocationVNum.Text = "Wear Location:";
            } else if (cmbType.SelectedIndex == 5) {
                // D
                fillComboboxRooms(cmbVNum);
                fillComboboxStates(cmbLocation);
                fillExits(cmbExits);

                lblVNum.Enabled = true;
                lblLimit.Enabled = true;
                lblLocationVNum.Enabled = true;
                lblLimit2.Enabled = false;
                cmbVNum.Enabled = true;
                txtLimit.Visible = false;
                cmbExits.Visible = true;
                cmbLocation.Enabled = true;
                txtLimit2.Enabled = false;

                lblVNum.Text = "Room VNum:";
                lblLimit.Text = "Exit Direction:";
                lblLocationVNum.Text = "Door State:";
            } else if (cmbType.SelectedIndex == 6) {
                // R
                fillComboboxRooms(cmbVNum);

                cmbExits.Items.Clear();
                cmbExits.Items.Add("4 - NWES");
                cmbExits.Items.Add("6 - NWESDU");
                cmbExits.SelectedIndex = 0;

                lblVNum.Enabled = true;
                lblLimit.Enabled = true;
                lblLocationVNum.Enabled = false;
                lblLimit2.Enabled = false;
                cmbVNum.Enabled = true;
                txtLimit.Visible = false;
                cmbExits.Visible = true;
                cmbLocation.Enabled = false;
                txtLimit2.Enabled = false;

                lblVNum.Text = "Room VNum:";
                lblLimit.Text = "Randomize:";
            }

            #endregion
        }

        private void fillComboboxMobs(ComboBox combo) {
            combo.Items.Clear();

            IOrderedEnumerable<Mobile> query = from Mobile m in ah.area.Mobs
                                               orderby m.VNum
                                               select m;

            foreach (Mobile m in query)
                combo.Items.Add(String.Format("#{0} - {1}", m.VNum, m.Name));

            combo.SelectedIndex = 0;
        }

        private void fillComboboxRooms(ComboBox combo) {
            combo.Items.Clear();

            IOrderedEnumerable<Room> query = from Room r in ah.area.Rooms
                                             orderby r.VNum
                                             select r;

            foreach (Room r in query)
                combo.Items.Add(String.Format("#{0} - {1}", r.VNum, r.Title));

            combo.SelectedIndex = 0;
        }

        private void fillComboboxItems(ComboBox combo) {
            combo.Items.Clear();

            IOrderedEnumerable<Item> query = from Item i in ah.area.Items
                                             orderby i.VNum
                                             select i;

            foreach (Item i in query)
                combo.Items.Add(String.Format("#{0} - {1}", i.VNum, i.Name));

            combo.SelectedIndex = 0;
        }

        private void fillComboboxItemsContainer(ComboBox combo) {
            combo.Items.Clear();

            IOrderedEnumerable<Item> query = from Item i in ah.area.Items
                                             where i.ItemType.Equals("container")
                                             orderby i.VNum
                                             select i;

            foreach (Item i in query)
                combo.Items.Add(String.Format("#{0} - {1}", i.VNum, i.Name));

            combo.SelectedIndex = 0;
        }

        private void fillComboboxWears(ComboBox combo) {
            combo.Items.Clear();

            Funcs.fillComboType(cmbLocation, "/types/wear/loc/@type", "/types/wear/loc", "");
        }

        private void fillComboboxStates(ComboBox combo) {
            combo.Items.Clear();

            Funcs.fillComboType(cmbLocation, "/types/resets/state/@type", "/types/resets/state", "");
        }

        private static void fillExits(ComboBox combo) {
            combo.Items.Clear();

            combo.Items.Add("0 - North");
            combo.Items.Add("1 - East");
            combo.Items.Add("2 - South");
            combo.Items.Add("3 - West");
            combo.Items.Add("4 - Up");
            combo.Items.Add("5 - Down");

            combo.SelectedIndex = 0;
        }

        private void btnCancel_Click(object sender, EventArgs e) {
            Dispose();
        }

        private static void selectVNum(ComboBox combo, int vnum) {
            var re = new Regex(@"#?(?<vnum>\-?\d+) ");

            for (int i = 0; i < combo.Items.Count; i++) {
                Match m = re.Match(combo.Items[i].ToString());

                if (m.Success && Int32.Parse(m.Groups["vnum"].Value) == vnum) {
                    combo.SelectedIndex = i;
                    return;
                }
            }
        }

        private void btnOK_Click(object sender, EventArgs e) {
            Reset r;

            if (inArray >= 0)
                r = (Reset) ah.area.Resets[inArray];
            else
                r = new Reset();

            r.Slot = 0;
            r.Type = getType(cmbType);
            r.VNum = getValue(cmbVNum);
            r.Limit = (txtLimit.Visible ? Int32.Parse(txtLimit.Text) : getValue(cmbExits));
            r.VNumWear = getValue(cmbLocation).ToString();
            r.ExtraParam = txtLimit2.Text;

            if (inArray < 0)
                ah.area.Resets.Add(r);
            Dispose();
        }

        private static int getValue(ComboBox combo) {
            var re = new Regex(@"#?(?<number>\-?\d+)");
            Match m = re.Match(combo.SelectedItem.ToString());

            if (m.Success)
                return Int32.Parse(m.Groups["number"].Value);

            return 0;
        }

        private static String getType(ComboBox combo) {
            var re = new Regex(@"#?(?<value>\w+)");
            Match m = re.Match(combo.SelectedItem.ToString());

            if (m.Success)
                return m.Groups["value"].Value;

            return "";
        }

        private void txtLimit_KeyPress(object sender, KeyPressEventArgs e) {
            if (e.KeyChar == 13)
                btnOK_Click(null, null);

            if (!Char.IsDigit(e.KeyChar))
                return;
        }

        private void txtLimit2_KeyPress(object sender, KeyPressEventArgs e) {
            if (e.KeyChar == 13)
                btnOK_Click(null, null);

            if (!Char.IsDigit(e.KeyChar))
                return;
        }

        private void btnPrev_Click(object sender, EventArgs e) {
            int newArray = inArray;

            try {
#pragma warning disable 168
                var r = (Reset) ah.area.Resets[newArray];
#pragma warning restore 168

                Form newForm = new frmResets(ah, newArray) { MdiParent = MdiParent };

                newForm.Location = new Point((MdiParent.Size.Width - newForm.Size.Width)/2 + 40,
                                             (MdiParent.Size.Height - newForm.Size.Height)/2 - 60);
                newForm.Show();

                Dispose();
            } catch (Exception) {
                MessageBox.Show("There are no more mobs to show!", "Whoops!", MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation);
            }
        }

        private void btnNext_Click(object sender, EventArgs e) {
            int newArray = inArray + 2;

            try {
#pragma warning disable 168
                var r = (Reset) ah.area.Resets[newArray];
#pragma warning restore 168

                Form newForm = new frmResets(ah, newArray) { MdiParent = MdiParent };

                newForm.Location = new Point((MdiParent.Size.Width - newForm.Size.Width)/2 + 40,
                                             (MdiParent.Size.Height - newForm.Size.Height)/2 - 60);
                newForm.Show();

                Dispose();
            } catch (Exception) {
                MessageBox.Show("There are no more resets to show!", "Whoops!", MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation);
            }
        }
    }
}